package com.neusoft.hifly.commons.lang;

import java.time.LocalDate;

import org.apache.commons.lang3.StringUtils;

/**
 * Title: 核心工具
 * <p>
 * Description: 版本号生成器
 * <p>
 * 软件版本号由四部分组成，第一个1为主版本号，第二个1为子版本号，第三个1为阶段版本号，第四部分为日期版本号加希腊字母版本号
 * <p>
 * 希腊字母版本号共有5种，分别为：Base, Alpha, Beta, RC, Release。例如：1.1.1.051021_Beta。
 * <p>
 * Copyright: 2019
 * <p>
 * Company: 东软汉枫
 *
 * @author lh_neu
 * @version 1.0.0
 */
public class Version {

	/**
	 * 版本前缀
	 */
	private static final String VERSION_PREFIX = "V";

	/**
	 * 主版本号 (ie 1.x.x)
	 */
	private final int major;

	/**
	 * 子版本号 (ie x.1.x)
	 */
	private final int minor;

	/**
	 * 修正版本号 (ie x.x.1)
	 */
	private final int micro;

	/**
	 * 状态的版本号（由开发人员更改，也可以不更改），可以是svn当前版本，也可以是yymmdd格式的日志。null表示没有。
	 */
	private final String statusVersion;

	/**
	 * 该产品的发布状态 (Base, Alpha, Beta, RC, Release)
	 */
	private final ReleaseStatus status;

	/**
	 * 版本字符串信息
	 */
	private String versionString;

	/**
	 * 构造方法，创建一个新的版本信息对象。
	 *
	 * @author lh_neu
	 * @date 2011-8-6 上午08:00:36
	 * @param major
	 *            主版本号
	 * @param minor
	 *            子版本号
	 * @param micro
	 *            修正版本号
	 * @param status
	 *            版本类型
	 * @param statusVersion
	 *            状态的版本号（由开发人员更改，也可以不更改）
	 */
	public Version(final int major, final int minor, final int micro, final ReleaseStatus status,
			final String statusVersion) {
		this.major = major;
		this.minor = minor;
		this.micro = micro;
		this.status = status;
		this.statusVersion = statusVersion;
		if (status != null) {
			if (status == ReleaseStatus.Release) {
				this.versionString = Version.VERSION_PREFIX + major + "." + minor + "." + micro;
			} else {
				if (StringUtils.isNotEmpty(statusVersion)) {
					this.versionString = Version.VERSION_PREFIX + major + "." + minor + "." + micro + "."
							+ statusVersion + "_" + status.toString();
				} else {
					this.versionString = Version.VERSION_PREFIX + major + "." + minor + "." + micro + "_"
							+ status.toString();
				}
			}
		} else {
			this.versionString = Version.VERSION_PREFIX + major + "." + minor + "." + micro;
		}
	}

	/**
	 * 服务器的发布状态
	 * <p>
	 * 枚举常量表示产品发布的安全类型。
	 * <p>
	 * 1、Base版：此版本表示该软件仅仅是一个假页面链接，通常包括所有的功能和页面布局，但是页面中的功能都没有做完整的实现，只是做为整体网站的一个基础架构
	 * <p>
	 * 2、Alpha版：此版本表示该软件在此阶段主要是以实现软件功能为主，通常只在软件开发者内部交流，一般而言，该版本软件的Bug较多，需要继续修改
	 * <p>
	 * 3、Beta版：该版本相对于α版已有了很大的改进，消除了严重的错误，但还是存在着一些缺陷，需要经过多次测试来进一步消除，此版本主要的修改对像是软件的UI
	 * <p>
	 * 4、RC版：（Release Candidate）该版本已经相当成熟了，基本上不存在导致错误的BUG，与即将发行的正式版相差无几
	 * <p>
	 * 5、Release版：该版本意味“最终版本”，在前面版本的一系列测试版之后，终归会有一个正式版本，是最终交付用户使用的一个版本。该版本有时也称为标准版。一般情况下，
	 * Release不会以单词形式出现在软件封面上，取而代之的是符号(Ｒ)
	 */
	public enum ReleaseStatus {
		Base("Base"), Alpha("Alpha"), Beta("Beta"), RC("RC"), Release("");

		// 版本
		private String status;

		/**
		 * 设置版本
		 *
		 * @param status
		 *            版本
		 */
		private ReleaseStatus(final String status) {
			this.status = status;
		}

		/**
		 * 输出版本
		 *
		 * @return 版本
		 */

		@Override
		public String toString() {
			return this.status;
		}
	}

	/**
	 * 返回一个String（即major.minor.revision）类型的版本号。
	 *
	 * @return 版本号。
	 */
	public String getVersionString() {
		return this.versionString;
	}

	/**
	 * Returns the release status of this product.
	 *
	 * @return the release status of this product.
	 */
	public ReleaseStatus getStatus() {
		return this.status;
	}

	/**
	 * Obtain the major release number for this product.
	 *
	 * @return The major release number 1.x.x
	 */
	public int getMajor() {
		return this.major;
	}

	/**
	 * Obtain the minor release number for this product.
	 *
	 * @return The minor release number x.1.x
	 */
	public int getMinor() {
		return this.minor;
	}

	/**
	 * Obtain the micro release number for this product.
	 *
	 * @return The micro release number x.x.1
	 */
	public int getMicro() {
		return this.micro;
	}

	/**
	 * Obtain the status relase number for this product. For example, if the release status is <strong>alpha</strong>
	 * the release may be <strong>5</strong> resulting in a release status of <strong>Alpha 5</strong>.
	 *
	 * @return The status version or -1 if none is set.
	 */
	public String getStatusVersion() {
		return this.statusVersion;
	}

	/**
	 * 演示
	 *
	 * @author lh_neu
	 * @date 2011-8-6 上午08:21:36
	 * @param args
	 *            参数
	 */
	public static void main(final String[] args) {
		// 生成版本号

		// 字符串类型的版本
		final Version version = new Version(1, 0, 2, Version.ReleaseStatus.valueOf("RC"),
				LocalDateUtil.dateToStr(LocalDate.now(), "uuMMdd"));

		// 显示版本号：1.0.2.113806_Alpha
		System.out.println(version.getVersionString());

		// 提取版本号单独使用
		final String hasVersion = version.getMajor() + "." + version.getMinor() + "." + version.getMicro();

		// 1.0.2
		System.out.println(hasVersion);
	}
}
